package com.ruoyi.business.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.ruoyi.business.domain.JtTraceabilityReport;
import com.ruoyi.business.service.IJtTraceabilityReportService;
import com.ruoyi.business.vo.FileInfoVo;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.utils.JtImageUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.business.domain.JtProductTraceability;
import com.ruoyi.business.service.IJtProductTraceabilityService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 产品溯源Controller
 * 
 * @author Alan Zhang
 * @date 2025-03-29
 */
@Controller
@RequestMapping("/business/traceability")
public class JtProductTraceabilityController extends BaseController
{
    private String prefix = "business/traceability";

    @Autowired
    private IJtProductTraceabilityService jtProductTraceabilityService;
    @Autowired
    private IJtTraceabilityReportService jtTraceabilityReportService;
    @Autowired
    private ServerConfig serverConfig;

    @RequiresPermissions("business:traceability:view")
    @GetMapping()
    public String traceability()
    {
        return prefix + "/traceability";
    }

    /**
     * 查询产品溯源列表
     */
    @RequiresPermissions("business:traceability:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(JtProductTraceability jtProductTraceability)
    {
        startPage();
        List<JtProductTraceability> list = jtProductTraceabilityService.selectJtProductTraceabilityList(jtProductTraceability);
        return getDataTable(list);
    }

    /**
     * 导出产品溯源列表
     */
    @RequiresPermissions("business:traceability:export")
    @Log(title = "产品溯源", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(JtProductTraceability jtProductTraceability)
    {
        List<JtProductTraceability> list = jtProductTraceabilityService.selectJtProductTraceabilityList(jtProductTraceability);
        ExcelUtil<JtProductTraceability> util = new ExcelUtil<JtProductTraceability>(JtProductTraceability.class);
        return util.exportExcel(list, "产品溯源数据");
    }

    /**
     * 新增产品溯源
     */
    @RequiresPermissions("business:traceability:add")
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存产品溯源
     */
    @RequiresPermissions("business:traceability:add")
    @Log(title = "产品溯源", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult addSave(JtProductTraceability jtProductTraceability, @RequestParam(value = "file", required = false)MultipartFile file,
                              @RequestParam(value = "oFile", required = false) MultipartFile oFile) throws IOException {

        if (file != null) {
            jtProductTraceability.setReportImageUrl(JtImageUtil.uploadTraceability(file, true));
        }
        if (oFile != null) {
            jtProductTraceability.setTestReportUrl(JtImageUtil.uploadTraceability(file, true));
        }
        return toAjax(jtProductTraceabilityService.insertJtProductTraceability(jtProductTraceability));
    }

    /**
     * 修改产品溯源
     */
    @RequiresPermissions("business:traceability:edit")
    @GetMapping("/edit/{traceabilityId}")
    public String edit(@PathVariable("traceabilityId") Long traceabilityId, ModelMap mmap)
    {
        JtProductTraceability jtProductTraceability = jtProductTraceabilityService.selectJtProductTraceabilityByTraceabilityId(traceabilityId);
        mmap.put("jtProductTraceability", jtProductTraceability);
        showFile(traceabilityId, mmap);
        return prefix + "/edit";
    }

    /**
     * 修改保存产品溯源
     */
    @RequiresPermissions("business:traceability:edit")
    @Log(title = "产品溯源", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult editSave(JtProductTraceability jtProductTraceability, @RequestParam(value = "file", required = false) MultipartFile file,
                               @RequestParam(value = "oFile", required = false) MultipartFile oFile) throws IOException {
        JtProductTraceability productTraceabilityDb = jtProductTraceabilityService.selectJtProductTraceabilityByTraceabilityId(jtProductTraceability.getTraceabilityId());
        if (file != null) {
            jtProductTraceability.setReportImageUrl(JtImageUtil.uploadTraceability(file, true));

            String oldImageUrl = productTraceabilityDb.getReportImageUrl();
            if(StringUtils.isEmpty(oldImageUrl)){
                JtImageUtil.deleteFile(oldImageUrl);
            }
        }

        if (oFile != null) {
            jtProductTraceability.setTestReportUrl(JtImageUtil.uploadTraceability(oFile, true));

            String testReportUrl = productTraceabilityDb.getTestReportUrl();
            if(StringUtils.isEmpty(testReportUrl)){
                JtImageUtil.deleteFile(testReportUrl);
            }
        }
        return toAjax(jtProductTraceabilityService.updateJtProductTraceability(jtProductTraceability));
    }

    /**
     * 删除产品溯源
     */
    @RequiresPermissions("business:traceability:remove")
    @Log(title = "产品溯源", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(jtProductTraceabilityService.deleteJtProductTraceabilityByTraceabilityIds(ids));
    }


    /**
     * 新增产品溯源
     */
    @RequiresPermissions("business:traceability:upload")
    @GetMapping("/upload/report")
    public String uploadReport(Long traceabilityId, ModelMap mmap)
    {
        mmap.put("traceabilityId",traceabilityId);
        showFile(traceabilityId, mmap);

        return prefix + "/uploadReport";
    }

    private void showFile(Long traceabilityId, ModelMap mmap){
        JtTraceabilityReport param = new JtTraceabilityReport();
        param.setTraceabilityId(traceabilityId);
        List<JtTraceabilityReport> list = jtTraceabilityReportService.selectJtTraceabilityReportList(param);

        List<String> urlList = new ArrayList<>();
        List<FileInfoVo> imageVoList = new ArrayList<>();

        List<String> fileUrlList = new ArrayList<>();
        List<FileInfoVo> fileInfoVoList = new ArrayList<>();
        for(JtTraceabilityReport item: list){
            if(StringUtils.isNotEmpty(item.getReportImageUrl())) {
                FileInfoVo imageVo = new FileInfoVo();
                imageVo.setCaption("检查报告图片");
                imageVo.setUrl("");
                imageVo.setDownloadUrl(item.getReportImageUrl());
                imageVo.setKey(item.getReportId());
                imageVoList.add(imageVo);

                urlList.add(item.getReportImageUrl());
            }
            if(StringUtils.isNotEmpty(item.getTestReportUrl())) {
                FileInfoVo fileVo = new FileInfoVo();
                fileVo.setCaption("检查报告");
                fileVo.setUrl("");
                fileVo.setDownloadUrl(item.getTestReportUrl());
                fileVo.setKey(item.getReportId());
                fileInfoVoList.add(fileVo);

                fileUrlList.add(item.getTestReportUrl());
            }
        }
        AjaxResult ajax = AjaxResult.success();
        ajax.put("url", urlList);
        ajax.put("config", imageVoList);
        mmap.put("imgInfo",ajax);

        AjaxResult fileAjax = AjaxResult.success();
        fileAjax.put("url", fileUrlList);
        fileAjax.put("config", fileInfoVoList);
        mmap.put("fileInfo", fileAjax);
    }

    /**
     * 新增保存图片
     */
    @RequiresPermissions("business:traceability:upload")
    @Log(title = "产品溯源-文件报告/图", businessType = BusinessType.INSERT)
    @PostMapping("/upload/save/report")
    @ResponseBody
    public AjaxResult saveReport(JtTraceabilityReport traceabilityReport)
    {
        try {
            int rows = jtTraceabilityReportService.insertJtTraceabilityReport(traceabilityReport);
            if (rows > 0) {
                AjaxResult ajax = new AjaxResult();
                ajax.put("code", 0);
                ajax.put("msg", "上传成功!");
                ajax.put("imgId", traceabilityReport.getReportId());
                return ajax;
            } else {
                return error("上传失败!");
            }
        } catch (Exception ex){
            if(ex instanceof DataIntegrityViolationException){
                JtImageUtil.deleteFile(traceabilityReport.getTestReportUrl());
                return error("请检查上传文件名称是否太长。"+ex.getCause());
            } else {
                return error(ex.getMessage());
            }
        }
    }

    @RequiresPermissions("business:traceability:remove")
    @Log(title = "产品溯源-检查报告/图", businessType = BusinessType.UPDATE)
    @PostMapping("/deleteFile/{type}")
    @ResponseBody
    public AjaxResult deleteFile(Long key,@PathVariable("type") int type){
        JtTraceabilityReport jtTraceabilityReport = jtTraceabilityReportService.selectJtTraceabilityReportByReportId(key);
        JtTraceabilityReport entity = new JtTraceabilityReport();
        entity.setReportId(key);
        //图
        if(type ==1 && StringUtils.isNotEmpty(jtTraceabilityReport.getReportImageUrl())){
            JtImageUtil.deleteFile(jtTraceabilityReport.getReportImageUrl());
        }
        //报告
        if(type==2 && StringUtils.isNotEmpty(jtTraceabilityReport.getTestReportUrl())){
            JtImageUtil.deleteFile(jtTraceabilityReport.getTestReportUrl());
        }
        int rows = jtTraceabilityReportService.deleteJtTraceabilityReportByReportId(key);
        return toAjax(rows);
    }

    /**
     * 上传请求
     */
    @PostMapping("/upload/file")
    @ResponseBody
    public AjaxResult uploadFile(MultipartFile file)
    {
        try {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadProductTraceabilityPath();
            // 上传并返回新文件名称
            String fileName;
            String extension = FileUploadUtils.getExtension(file);
            boolean isAllowed = FileUploadUtils.isAllowedExtension(extension, MimeTypeUtils.IMAGE_EXTENSION);

            if(isAllowed && file.getSize() > 1024 * 3){
                //压缩文件
                fileName = FileUploadUtils.upload(filePath, file, true, true);
            } else {
                //不压缩
                fileName = FileUploadUtils.upload(filePath, file);
            }
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            return ajax;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }


    @RequiresPermissions("business:traceability:edit")
    @Log(title = "产品溯源-图排序", businessType = BusinessType.UPDATE)
    @PostMapping("/save/file/sort")
    @ResponseBody
    public AjaxResult picturesSorting(String[] ids){
        if(StringUtils.isEmpty(ids) || ids.length == 0){
            return error("排序失败！");
        }
        int i = 1;
        List<JtTraceabilityReport> list = new ArrayList<>();
        for (String idStr : ids){
            if(StringUtils.isNotEmpty(idStr)){
                JtTraceabilityReport entity = new JtTraceabilityReport();
                entity.setReportId(Long.valueOf(idStr));
                entity.setSortValue(i);
                list.add(entity);
                i++;
            }
        }
        int rows = jtTraceabilityReportService.bathUpdateSaveSort(list);
        return toAjax(rows);
    }
}
